﻿using System;
using System.Runtime.InteropServices;

namespace SDK {
    public class MagService : IMagService {
        public MagService() : base() {
        }

        [Obsolete("Use MagService() instead", false)]
        public MagService(IntPtr wnd) : base(wnd) {
        }
    }

    public class IMagService {
        private const uint mChannel = 0;
        private bool mIsInitialized;

        public IMagService() {
            mIsInitialized = newChannel(mChannel);
        }

        public bool IsUsingStaticIp() {
            return GroupSDK.MAG_IsUsingStaticIp();
        }

        public uint GetLocalIp() {
            if (!mIsInitialized) {
                mIsInitialized = newChannel(mChannel);
            }

            return mIsInitialized ? GroupSDK.MAG_GetLocalIp() : 0;
        }

        public void EnableAutoReConnect(bool bEnable) {
            GroupSDK.MAG_EnableAutoReConnect(bEnable);
        }

        public bool EnumCameras() {
            if (!mIsInitialized) {
                mIsInitialized = newChannel(mChannel);
            }

            return mIsInitialized ? GroupSDK.MAG_EnumCameras() : false;
        }

        public uint GetTerminalList(GroupSDK.ENUM_INFO[] list, uint count) {
            if (!mIsInitialized) {
                return 0;
            }

            uint size = (uint)Marshal.SizeOf(typeof(GroupSDK.CAMERA_INFO)) * count;

            IntPtr ptr = Marshal.AllocHGlobal((int)size);
            IntPtr ptrBackup = ptr;

            uint devNum = GroupSDK.MAG_GetTerminalList(ptr, size);

            for (int i = 0; i < devNum; i++) {
                list[i] = (GroupSDK.ENUM_INFO)Marshal.PtrToStructure(ptr, typeof(GroupSDK.ENUM_INFO));
                // .net framework 4.0 及以上
                ptr = ptr + Marshal.SizeOf(typeof(GroupSDK.ENUM_INFO));
                // .net framework 4.0 以下
                // x86
                //ptr = (IntPtr)((int)ptr + Marshal.SizeOf(typeof(GroupSDK.ENUM_INFO)));
                // x64
                //ptr = (IntPtr)((long)ptr + Marshal.SizeOf(typeof(GroupSDK.ENUM_INFO)));
            }

            Marshal.FreeHGlobal(ptrBackup);
            return devNum;
        }

        public uint GetTerminalCount() {
            return mIsInitialized ? GroupSDK.MAG_GetTerminalList(IntPtr.Zero, 0) : 0;
        }

        public int CompressDDT(byte[] dstBuffer, uint dstBufferSize, byte[] srcBuffer, uint srcBufferSize, uint quality) {
            return GroupSDK.MAG_CompressDDT(dstBuffer, dstBufferSize, srcBuffer, srcBufferSize, quality);
        }

        public int DeCompressDDT(byte[] dstBuffer, uint dstBufferSize, byte[] srcBuffer, uint srcBufferSize) {
            return GroupSDK.MAG_DeCompressDDT(dstBuffer, dstBufferSize, srcBuffer, srcBufferSize);
        }

        private bool newChannel(uint channelIndex) {
            if (!GroupSDK.MAG_IsChannelAvailable(channelIndex)) {
                if (!GroupSDK.MAG_NewChannel(channelIndex)) {
                    return false;
                }
            }

            if (!GroupSDK.MAG_IsInitialized(channelIndex)) {
                if (!GroupSDK.MAG_Initialize(channelIndex, IntPtr.Zero)) {
                    GroupSDK.MAG_DelChannel(channelIndex);
                    return false;
                }
            }

            return true;
        }

        #region Deprecated apis, will be deleted later!!

        [Obsolete("Use MagDevice() instead", false)]
        public IMagService(IntPtr wnd) {
        }

        [Obsolete("Not needed", false)]
        public bool Initialize() {
            return true;
        }

        [Obsolete("Not needed", false)]
        public void DeInitialize() {
        }

        [Obsolete("Not needed", false)]
        public bool IsInitialized() {
            return true;
        }

        [Obsolete("Not needed", false)]
        public bool IsLanConnected() {
            return true;
        }

        [Obsolete("Deprecated", true)]
        public bool IsDHCPServerRunning() {
            return false;
        }

        [Obsolete("Deprecated", true)]
        public bool StartDHCPServer() {
            return false;
        }

        [Obsolete("Deprecated", true)]
        public void StopDHCPServer() {
        }

        [Obsolete("Use CompressDDT(byte[] dstBuffer, uint dstBufferSize, byte[] srcBuffer, uint srcBufferSize, uint quality) instead", false)]
        public int CompressDDT(IntPtr dstBuffer, uint dstBufferSize, IntPtr srcBuffer, uint srcBufferSize, uint quality) {
            return GroupSDK.MAG_CompressDDT(dstBuffer, dstBufferSize, srcBuffer, srcBufferSize, quality);
        }

        [Obsolete("Use DeCompressDDT(byte[] dstBuffer, uint dstBufferSize, byte[] srcBuffer, uint srcBufferSize) instead", false)]
        public int DeCompressDDT(IntPtr dstBuffer, uint dstBufferSize, IntPtr srcBuffer, uint srcBufferSize) {
            return GroupSDK.MAG_DeCompressDDT(dstBuffer, dstBufferSize, srcBuffer, srcBufferSize);
        }
        #endregion
    }
}
